const UNIT_GROUPS = {
  length: {
    base: "m",
    units: {
      m: 1,
      km: 1000,
      cm: 0.01,
      mm: 0.001,
      in: 0.0254,
      ft: 0.3048,
      yd: 0.9144,
      mi: 1609.344,
    },
  },
  weight: {
    base: "kg",
    units: {
      kg: 1,
      g: 0.001,
      lb: 0.45359237,
      oz: 0.028349523125,
    },
  },
  area: {
    base: "m2",
    units: {
      m2: 1,
      km2: 1_000_000,
      ft2: 0.09290304,
      in2: 0.00064516,
    },
  },
  volume: {
    base: "m3",
    units: {
      m3: 1,
      l: 0.001,
      ml: 0.000001,
      ft3: 0.028316846592,
      in3: 0.000016387064,
      gal: 0.003785411784,
    },
  },
};

export class UnitConverter {
  constructor(root) {
    this.root = root;
    this.render();
  }
  render() {
    this.root.innerHTML = `
      <div class="row">
        <select id="unitGroup">
          <option value="length">Length</option>
          <option value="weight">Weight</option>
          <option value="area">Area</option>
          <option value="volume">Volume</option>
        </select>
      </div>
      <div class="row">
        <input id="uAmount" type="number" step="0.0001" value="1" />
        <select id="uFrom"></select>
        <span>→</span>
        <select id="uTo"></select>
      </div>
      <div class="display" id="uResult">0</div>
    `;
    this.groupEl = this.root.querySelector("#unitGroup");
    this.amountEl = this.root.querySelector("#uAmount");
    this.fromEl = this.root.querySelector("#uFrom");
    this.toEl = this.root.querySelector("#uTo");
    this.resultEl = this.root.querySelector("#uResult");
    this.groupEl.addEventListener("change", () => this.populateUnits());
    ["input", "change"].forEach((evt) => {
      this.amountEl.addEventListener(evt, () => this.update());
      this.fromEl.addEventListener(evt, () => this.update());
      this.toEl.addEventListener(evt, () => this.update());
    });
    this.populateUnits();
  }
  populateUnits() {
    const group = UNIT_GROUPS[this.groupEl.value];
    this.fromEl.innerHTML = "";
    this.toEl.innerHTML = "";
    for (const u of Object.keys(group.units)) {
      const o1 = document.createElement("option");
      o1.value = u;
      o1.textContent = u;
      this.fromEl.appendChild(o1);
      const o2 = document.createElement("option");
      o2.value = u;
      o2.textContent = u;
      this.toEl.appendChild(o2);
    }
    this.fromEl.value = group.base;
    this.toEl.value = Object.keys(group.units)[0];
    this.update();
  }
  update() {
    const group = UNIT_GROUPS[this.groupEl.value];
    const amount = Number(this.amountEl.value || "0");
    const from = this.fromEl.value;
    const to = this.toEl.value;
    const toBase = amount * group.units[from];
    const result = toBase / group.units[to];
    this.resultEl.textContent = `${result.toFixed(6)} ${to}`;
  }
}
